"""
Redis悲观锁
基本语法
    SETNX命令
        键不存在才会设置成功
        多个客户端抢夺, 只有一个可以设置成功(获取锁, 获取操作数据的权限)

SETNX lock1  1   # 键不存在,才会设置成功
$ 1
SETNX lock1  1   # 键存在, 无法设置, 返回0
$ 0

注意点:
    给锁设置过期时间, 超出5秒, 自动删除锁, 避免出现死锁现象
"""
import time

from redis import StrictRedis

# 创建redis连接
redis_client = StrictRedis(decode_responses=True)

# 设计redis悲观锁 处理秒杀超卖问题

while True:
    # 让客户端抢锁 setnx
    order_lock = redis_client.setnx('lock:order', 1)
    if order_lock:  # 抢到锁,可以查询并修改库
        redis_client.expire('lock:order', 5)  # 给锁设置过期时间,防止死锁,超出5秒,自动删除锁

        reserve_count = redis_client.get('count:reserve')
        # 判断库存
        if int(reserve_count) > 0:
            # 库存减一
            redis_client.decr('count:reserve')
            print("生成订单")
        else:
            print("已售罄")
        # 完成处理, 移除锁
        redis_client.delete('lock:order')
        break
    else:
        # 没有抢到锁, 等待并继续抢锁
        print("没有抢到锁,等待并重试")
        time.sleep(1)
        continue
